package dev.ece.suit.text;

import org.lwjgl.opengl.GL20;

import dev.ece.core.shader.Shader;
import dev.ece.core.texture.Texture;
import dev.ece.util.lib.Vector4f;

/**
 * @author 潜行的青衣
 * @see
 */
public class TextLibShader extends Shader {
	
	public static final String VERTEX_SHADER_SOURCE = "uniform float ece_OffsetX;\n" + 
			"uniform float ece_OffsetY;\n" +
			"uniform float ece_FontSize;\n" +
			"uniform float ece_DefaultFontSize;\n" +
			"attribute vec4 ece_Vertex;\n" +
			"attribute vec2 ece_TexCoord;\n" +
			"varying vec2 t_texCoord;\n" +
			"void main() {\n" + 
				"vec3 vertex = vec3(ece_Vertex.x + ece_OffsetX, ece_Vertex.y + ece_OffsetY, ece_Vertex.z) * ece_FontSize / ece_DefaultFontSize;" +
				"gl_Position = ece_ModelViewProjectionMatrix * vec4(vertex, 1.0);\n" +
				"t_texCoord = ece_TexCoord;\n" +
			"}";

	public static final String PIXEL_SHADER_SOURCE = "uniform sampler2D ece_TextTexture;\n" +
			"uniform vec4 ece_Color;\n" +
			"varying vec2 t_texCoord;\n" +
			"void main() {\n" +
				"float alpha = texture2D(ece_TextTexture, t_texCoord).a;\n" +
				"gl_FragColor = vec4(ece_Color.rgb, alpha);\n" +
			"}";

	private static TextLibShader textShader = new TextLibShader();
	
	private int textureHandler;
	
	private int colorHandler;
	
	private int offsetXHandler;
	
	private int offsetYHandler;
	
	private int fontSizeHandler;
	
	private int defaultFontSizeHandler;
	
	private TextLibShader() {
		super(VERTEX_SHADER_SOURCE, PIXEL_SHADER_SOURCE);
	}

	@Override
	protected void onBindAttribLocations(int program) {
		GL20.glBindAttribLocation(program, 0, "ece_Vertex");
		GL20.glBindAttribLocation(program, 1, "ece_TexCoord");
	}

	@Override
	protected void onInitializeHandler(int program) {
		offsetXHandler = GL20.glGetUniformLocation(program, "ece_OffsetX");
		offsetYHandler = GL20.glGetUniformLocation(program, "ece_OffsetY");
		fontSizeHandler = GL20.glGetUniformLocation(program, "ece_FontSize");
		defaultFontSizeHandler = GL20.glGetUniformLocation(program, "ece_DefaultFontSize");
		textureHandler = GL20.glGetUniformLocation(program, "ece_TextTexture");
		colorHandler = GL20.glGetUniformLocation(program, "ece_Color");
		
	}
	
	public void glTexture(Texture texture) {
		GL20.glUniform1i(textureHandler, texture.bind(0));
	}
	
	public void glColor(Vector4f color) {
		color.glUniform4f(colorHandler);
	}
	
	public void glOffsetX(float offset_x) {
		GL20.glUniform1f(offsetXHandler, offset_x);
	}
	
	public void glOffsetY(float offset_y) {
		GL20.glUniform1f(offsetYHandler, offset_y);
	}
	
	public void glFontSize(float fontSize) {
		GL20.glUniform1f(fontSizeHandler, fontSize);
	}
	
	public void glDefaultFontSize(float fontSize) {
		GL20.glUniform1f(defaultFontSizeHandler, fontSize);
	}

	public int getTextureHandler() {
		return textureHandler;
	}

	public static TextLibShader getInstance() {
		return textShader;
	}
	
	@Override
	public void destroy() {
		textShader = null;
		super.destroy();
	}

	@Override
	public void clearup() {
		GL20.glDeleteShader(offsetXHandler);
		GL20.glDeleteShader(offsetYHandler);
		GL20.glDeleteShader(fontSizeHandler);
		GL20.glDeleteShader(defaultFontSizeHandler);
		GL20.glDeleteShader(textureHandler);
		GL20.glDeleteShader(colorHandler);
		super.clearup();
	}
	
}
